package com.shockweb.common.gzip;


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.io.ByteArrayInputStream;
/**
 * Gzip压缩和解压
 * @author pengminghua
 *
 */
public class Gzip {
	
	/**
	 * 压缩字符串
	 * @param source
	 * @param charsetName
	 * @return byte[]
	 * @throws IOException
	 */
	public static byte[] compress(String source,String charsetName) throws IOException{	
		return compress(source.getBytes(charsetName));
	}
	
	/**
	 * 压缩字符串
	 * @param source
	 * @return byte[]
	 * @throws IOException
	 */
	public static byte[] compress(String source) throws IOException{	
		return compress(source.getBytes());
	}	
	
	/**
	 * 将数据压缩到输出流
	 * @param source
	 * @param out
	 * @throws IOException
	 */
	public static void compress(byte[] source,OutputStream out) throws IOException{
		GZIPOutputStream gzip = null;
		try{
			gzip = new GZIPOutputStream(out);
			gzip.write(source);
			gzip.finish();
			out.flush();
		}catch(IOException e){
			if(gzip!=null){
				try{
					gzip.close();
				}catch(IOException e1){
				}
			}
			throw e;
		}
	}
	
	
	/**
	 * 压缩字节
	 * @param source
	 * @return byte[]
	 * @throws IOException
	 */
	public static byte[] compress(byte[] source) throws IOException{	
		ByteArrayOutputStream out = null;
		try{
			out = new ByteArrayOutputStream();
			compress(source,out);
			return out.toByteArray();
		}catch(IOException e){
			if(out!=null){
				try{
					out.close();
				}catch(IOException e1){
				}
			}
			throw e;
		}
	}
	
	/**
	 * 从流解压缩到字节
	 * @param in
	 * @return byte[]
	 * @throws IOException
	 */
	public static byte[] decompressBytes(InputStream in)throws IOException{
		GZIPInputStream gzip = null;
		byte[] rtn = null;
		try{
			gzip = new GZIPInputStream(in);
			byte[] cache = null;
			int readSize = 1;
			ArrayList<byte[]> al = new ArrayList<byte[]>();
			ArrayList<Integer> al2 = new ArrayList<Integer>();
			while(readSize>0){
				cache = new byte[1024];
				readSize = gzip.read(cache);
				if(readSize>0){
					al.add(cache);
					al2.add(new Integer(readSize));
				}
			}
			int Len = 0;
			for(Integer inte:al2){
				Len = Len + inte.intValue();
			}
			rtn = new byte[Len];
			int k=0;
			for(int i=0;i<al.size();i++){
				byte[] bytes = al.get(i);
				for(int j=0;j<al2.get(i).intValue();j++){
					rtn[k] = bytes[j];
					k++;
				}
			}
			return rtn;
		}catch(IOException e){
			if(gzip!=null){
				try{
					gzip.close();
				}catch(IOException e1){
				}
			}
			throw e;
		}
	}
	
	
	/**
	 * 从字节解压缩到字节
	 * @param value
	 * @return byte[]
	 * @throws IOException
	 */
	public static byte[] decompressBytes(byte[] value)throws IOException{
		ByteArrayInputStream in = null;
		try{
			in = new ByteArrayInputStream(value);
			return decompressBytes(in);
		}catch(IOException e){
			if(in!=null){
				try{
					in.close();
				}catch(IOException e1){
				}
			}
			throw e;
		}
	}
	
	/**
	 * 从流解压缩到字符串
	 * @param in
	 * @return String
	 * @throws IOException
	 */
	public static String decompressString(InputStream in)throws IOException{
		return new String(decompressBytes(in));
	}
	/**
	 * 从字节解压缩到字符串
	 * @param value
	 * @return String
	 * @throws IOException
	 */
	public static String decompressString(byte[] value)throws IOException{
		return new String(decompressBytes(value));
	}
	
	/**
	 * 从字节解压缩到字符串
	 * @param value
	 * @param charsetName
	 * @return String
	 * @throws IOException
	 */
	public static String decompressString(byte[] value,String charsetName)throws IOException{
		return new String(decompressBytes(value),charsetName);
	}
}
